package com.tencreat.common.core.utils;

import com.tencreat.common.entity.ImUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * token验证处理
 *
 * @Company: 深圳腾创互联科技有限公司
 * @link: https://tencreat.com/#/
 * @author tencreat
 */
@Component
public class JwtService
{
    // 令牌自定义标识
    @Value("${jwt.header}")
    private String header;
    // 令牌秘钥
    @Value("${jwt.secret}")
    private String secret;
    // 令牌秘钥
    @Value("${jwt.prefix}")
    private String prefix;

    protected static final long MILLIS_SECOND = 1000;

    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;

    protected static final long MILLIS_DAY = 60 * 60 * 24 * MILLIS_SECOND;

    private static final Long MILLIS_MINUTE_TEN = 10 * 60 * 1000L;

    /**
     * 获取用户身份信息
     */
    public Long getUserId(HttpServletRequest request)
    {
        // 获取请求携带的令牌
        String token = getToken(request);
        return getUserId(token);
    }
    /**
     * 获取用户身份信息
     */
    public ImUser getUser(HttpServletRequest request)
    {
        // 获取请求携带的令牌
        String token = getToken(request);
        return getUser(token);
    }

    /**
     * 获取用户身份信息 用于websocket验证
     *
     * @return 用户信息
     */
    public String getUserName(String token)
    {
        if (StringUtils.isNotEmpty(token) && token.startsWith(prefix))
        {
            token = token.replace(prefix, "");
        }
        if (StringUtils.isNotEmpty(token))
        {
            try {
                Claims claims = parseToken(token);
                return claims.getSubject();
            }catch (Exception e){
                return null;
            }
        }
        return null;
    }
    public Long getUserId(String token)
    {
        if (StringUtils.isNotEmpty(token) && token.startsWith(prefix))
        {
            token = token.replace(prefix, "");
        }
        if (StringUtils.isNotEmpty(token))
        {
            try {
                Claims claims = parseToken(token);
                return Long.valueOf(claims.getId());
            }catch (Exception e){
                return null;
            }
        }
        return null;
    }
    public ImUser getUser(String token)
    {
        if (StringUtils.isNotEmpty(token) && token.startsWith(prefix))
        {
            token = token.replace(prefix, "");
        }
        if (StringUtils.isNotEmpty(token))
        {
            try {
                ImUser imUser = new ImUser();
                Claims claims = parseToken(token);

                imUser.setId(Long.valueOf(claims.getId()));
                imUser.setUsername(claims.getSubject());
                return imUser;
            }catch (Exception e){
                return null;
            }
        }
        return null;
    }

    /**
     * 生成令牌
     */
    public String createToken(ImUser user)
    {
        Map<String, Object> claims = new HashMap<>();
        claims.put(Claims.SUBJECT, user.getUsername());
        claims.put(Claims.ID, user.getId());
//        claims.put(Claims.EXPIRATION, System.currentTimeMillis() + expire * MILLIS_DAY);

        String token = Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    private Claims parseToken(String token)
    {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }


    /**
     * 获取请求token
     *
     * @param request
     * @return token
     */
    private String getToken(HttpServletRequest request)
    {
        String token = request.getHeader(header);
        if (StringUtils.isNotEmpty(token) && token.startsWith(prefix))
        {
            token = token.replace(prefix, "");
        }
        return token;
    }
}
